#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <cmath>

// 计算两个矩形的角度差
double angleDifference(double angle1, double angle2) {
    double diff = std::abs(angle1 - angle2);
    return std::min(diff, 180.0 - diff);
}

int main() {
    // 读取图片
    cv::Mat image = cv::imread("test.jpg");
    if (image.empty()) {
        std::cout << "无法读取图片" << std::endl;
        return -1;
    }
    
    // 转换为HSV颜色空间
    cv::Mat hsv;
    cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
    
    // 定义蓝色的HSV范围
    cv::Scalar lower_blue(50, 50, 200);
    cv::Scalar upper_blue(140, 255, 255);
    
    // 创建蓝色掩码
    cv::Mat blue_mask;
    cv::inRange(hsv, lower_blue, upper_blue, blue_mask);
    
    // ========== 降噪处理 ==========
    
    // 方法1：形态学操作
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
    cv::Mat denoised_mask;
    
    // 开运算：去除小的白色杂点
    cv::morphologyEx(blue_mask, denoised_mask, cv::MORPH_OPEN, kernel);
    
    // 闭运算：填充白色区域内部的小黑洞
    cv::morphologyEx(denoised_mask, denoised_mask, cv::MORPH_CLOSE, kernel);

    // ========== 填充未填充区域 ==========
    
    // 使用轮廓填充方法确保所有闭合区域都被填充
    cv::Mat filled_mask = cv::Mat::zeros(denoised_mask.size(), CV_8UC1);
    
    // 查找所有轮廓
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(denoised_mask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    
    // 填充所有轮廓内部
    for (size_t i = 0; i < contours.size(); i++) {
        cv::drawContours(filled_mask, contours, (int)i, 255, -1);
    }
    
    // 可选：中值滤波平滑边缘
    cv::medianBlur(filled_mask, filled_mask, 3);
    
    // ========== 轮廓检测和矩形拟合 ==========
    
    // 重新检测填充后的轮廓
    std::vector<std::vector<cv::Point>> final_contours;
    cv::findContours(filled_mask.clone(), final_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    
    // 创建结果图像
    cv::Mat result_image = image.clone();
    
    int valid_contour_count = 0;
    std::vector<cv::RotatedRect> valid_rects;
    
    for (size_t i = 0; i < final_contours.size(); i++) {
        // ========== 轮廓过滤 ==========
        
        double area = cv::contourArea(final_contours[i]);
        if (area < 200) {
            continue;
        }
        
        double perimeter = cv::arcLength(final_contours[i], true);
        if (perimeter < 100) {
            continue;
        }
        
        cv::Rect bounding_rect = cv::boundingRect(final_contours[i]);
        double aspect_ratio = (double)bounding_rect.width / bounding_rect.height;
        if (aspect_ratio < 0.2) {
            continue;
        }
        
        // ========== 矩形拟合 ==========
        
        cv::RotatedRect rotated_rect = cv::minAreaRect(final_contours[i]);

        // ========== 标记矩形边框 ==========
        
        cv::Point2f vertices[4];
        rotated_rect.points(vertices);
        for (int j = 0; j < 4; j++) {
            cv::line(result_image, vertices[j], vertices[(j + 1) % 4], cv::Scalar(0, 255, 0), 2);
        }
        
        valid_rects.push_back(rotated_rect);
        valid_contour_count++;
        
        // 记录小矩形信息
        std::cout << "小矩形 " << valid_contour_count << ":" << std::endl;
        std::cout << "  - 中心: " << rotated_rect.center << std::endl;
        std::cout << "  - 尺寸: " << rotated_rect.size.width << " x " << rotated_rect.size.height << std::endl;
        std::cout << "  - 角度: " << rotated_rect.angle << "度" << std::endl;
    }

    // ========== 在相邻平行矩形间绘制大矩形 ==========
    
    for (size_t i = 0; i < valid_rects.size(); i++) {
        for (size_t j = i + 1; j < valid_rects.size(); j++) {
            // 检查两个矩形是否平行
            double angle_diff = angleDifference(valid_rects[i].angle, valid_rects[j].angle);
            
            if (angle_diff < 15.0) {
                cv::Point2f center1 = valid_rects[i].center;
                cv::Point2f center2 = valid_rects[j].center;
                
                // 计算两个中心点之间的距离
                double distance = cv::norm(center1 - center2);
                
                // 大矩形的中心点（两个小矩形中心的中间点）
                cv::Point2f big_center = (center1 + center2) * 0.5;
                
                // 比较小矩形长宽，确保正确识别
                double rect1_width = valid_rects[i].size.width;
                double rect1_height = valid_rects[i].size.height;
                double rect2_width = valid_rects[j].size.width;
                double rect2_height = valid_rects[j].size.height;
                
                // 计算两个小矩形的长度平均值（取较大的边作为长度）
                double rect1_length = std::max(rect1_width, rect1_height);
                double rect2_length = std::max(rect2_width, rect2_height);
                double avg_length = (rect1_length + rect2_length) / 2.0;
                
                // 计算大矩形的尺寸
                // 长度为两个小矩形长度平均值的2.5倍
                double big_length = avg_length * 2.5;
                
                // 宽度为两小矩形中心距离减去两小矩形平均宽度除以二
                double rect1_short = std::min(rect1_width, rect1_height);
                double rect2_short = std::min(rect2_width, rect2_height);
                double avg_short = (rect1_short + rect2_short) / 2.0;
                double big_width = distance - avg_short;
                
                // 确定大矩形的角度 - 确保长边与小矩形长边平行
                double big_angle = valid_rects[i].angle;
                
                // 检查是否需要调整角度（如果小矩形的宽度大于高度，需要调整90度）
                if (rect1_width > rect1_height) {
                    // 小矩形的长边是宽度方向，大矩形长边应该与此平行
                    // 角度已经正确，不需要调整
                } else {
                    // 小矩形的长边是高度方向，大矩形长边需要旋转90度
                    big_angle += 90.0;
                }
                
                // 标记大矩形中心（黄色圆）
                cv::circle(result_image, big_center, 8, cv::Scalar(0, 255, 255), -1);

                // 创建大矩形（使用调整后的角度）
                cv::RotatedRect big_rect(big_center, cv::Size2f(big_length, big_width), big_angle);
                
                // 绘制大矩形（绿色边框）
                cv::Point2f big_vertices[4];
                big_rect.points(big_vertices);
                for (int k = 0; k < 4; k++) {
                    cv::line(result_image, big_vertices[k], big_vertices[(k + 1) % 4], 
                            cv::Scalar(0, 255, 0), 3);
                }
                
                // 输出详细信息
                std::cout << "在矩形 " << i+1 << " 和 " << j+1 << " 之间绘制大矩形" << std::endl;
                std::cout << "  - 角度差: " << angle_diff << "度" << std::endl;
                std::cout << "  - 距离: " << distance << "像素" << std::endl;
                std::cout << "  - 矩形1尺寸: " << rect1_width << " x " << rect1_height << std::endl;
                std::cout << "  - 矩形2尺寸: " << rect2_width << " x " << rect2_height << std::endl;
                std::cout << "  - 平均长度: " << avg_length << "像素" << std::endl;
                std::cout << "  - 大矩形尺寸: " << big_length << " x " << big_width << std::endl;
                std::cout << "  - 大矩形角度: " << big_angle << "度" << std::endl;
                std::cout << "  - 大矩形中心: " << big_center << std::endl;
                std::cout << "----------------------------------------" << std::endl;
            }
        }
    }

    // ========== 显示结果 ==========
    
    cv::namedWindow("Final Result with Rectangles", cv::WINDOW_NORMAL);
    cv::imshow("Final Result with Rectangles", result_image);
    cv::waitKey(0);
    cv::destroyAllWindows();
    
    return 0;
}